#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
PCD到PLY格式转换工具
用于将PCD文件转换为CloudCompare可以直接打开的PLY格式
"""

import open3d as o3d
import os
import sys
import glob
import argparse

def convert_pcd_to_ply(input_path, output_path=None):
    """
    将PCD文件转换为PLY格式
    
    Args:
        input_path: 输入PCD文件路径
        output_path: 输出PLY文件路径（可选，默认替换扩展名）
    """
    try:
        # 检查输入文件是否存在
        if not os.path.exists(input_path):
            print(f"错误：文件不存在 {input_path}")
            return False
        
        # 读取PCD文件
        print(f"正在读取PCD文件: {input_path}")
        point_cloud = o3d.io.read_point_cloud(input_path)
        
        if len(point_cloud.points) == 0:
            print(f"警告：点云为空 {input_path}")
            return False
        
        # 生成输出路径
        if output_path is None:
            output_path = os.path.splitext(input_path)[0] + '.ply'
        
        # 保存为PLY格式
        print(f"正在保存PLY文件: {output_path}")
        success = o3d.io.write_point_cloud(output_path, point_cloud, write_ascii=True)
        
        if success:
            print(f"✓ 转换成功！")
            print(f"  点数: {len(point_cloud.points)}")
            print(f"  输出文件: {output_path}")
            return True
        else:
            print(f"✗ 保存失败: {output_path}")
            return False
            
    except Exception as e:
        print(f"转换失败: {str(e)}")
        return False

def batch_convert(input_dir, output_dir=None):
    """
    批量转换目录中的所有PCD文件
    
    Args:
        input_dir: 输入目录
        output_dir: 输出目录（可选，默认与输入目录相同）
    """
    if not os.path.exists(input_dir):
        print(f"错误：目录不存在 {input_dir}")
        return
    
    # 查找所有PCD文件
    pcd_files = glob.glob(os.path.join(input_dir, "*.pcd"))
    
    if not pcd_files:
        print(f"在目录 {input_dir} 中未找到PCD文件")
        return
    
    print(f"找到 {len(pcd_files)} 个PCD文件")
    
    success_count = 0
    for pcd_file in pcd_files:
        # 生成输出路径
        if output_dir:
            if not os.path.exists(output_dir):
                os.makedirs(output_dir)
            basename = os.path.basename(pcd_file)
            ply_file = os.path.join(output_dir, os.path.splitext(basename)[0] + '.ply')
        else:
            ply_file = None
        
        # 转换文件
        if convert_pcd_to_ply(pcd_file, ply_file):
            success_count += 1
        print()  # 空行分隔
    
    print(f"批量转换完成: {success_count}/{len(pcd_files)} 个文件成功转换")

def main():
    parser = argparse.ArgumentParser(description='PCD到PLY格式转换工具')
    parser.add_argument('input', help='输入PCD文件或目录路径')
    parser.add_argument('-o', '--output', help='输出PLY文件或目录路径')
    parser.add_argument('-b', '--batch', action='store_true', help='批量转换模式（输入必须是目录）')
    
    args = parser.parse_args()
    
    if args.batch:
        # 批量转换模式
        batch_convert(args.input, args.output)
    else:
        # 单文件转换模式
        if os.path.isdir(args.input):
            print("输入是目录，使用 -b 选项进行批量转换")
            return
        
        convert_pcd_to_ply(args.input, args.output)

if __name__ == '__main__':
    # 如果没有命令行参数，显示帮助信息
    if len(sys.argv) == 1:
        print("PCD到PLY格式转换工具")
        print("=" * 50)
        print("使用方法:")
        print("  单文件转换: python3 convert_pcd_to_ply.py input.pcd [-o output.ply]")
        print("  批量转换:   python3 convert_pcd_to_ply.py input_dir -b [-o output_dir]")
        print()
        print("示例:")
        print("  python3 convert_pcd_to_ply.py /path/to/pointcloud.pcd")
        print("  python3 convert_pcd_to_ply.py /path/to/pcd_files -b")
        print("  python3 convert_pcd_to_ply.py /path/to/pcd_files -b -o /path/to/ply_files")
        print()
        print("转换后的PLY文件可以直接用CloudCompare打开")
    else:
        main()
